package com.tsx.dictionary.utils;

import com.tsx.dictionary.enums.BaseEnum;
import com.tsx.dictionary.function.IFunction;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

@Slf4j
public class DictionaryUtil {
    public static <E extends BaseEnum> List<Map<String, Object>> getDictionaryList(Class<E> clazz) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        Arrays.stream(clazz.getEnumConstants())
                .forEach(enumItem -> {
                    Map<String, Object> item = new HashMap<>(2);
                    item.put("code", enumItem.getCode());
                    item.put("desc", enumItem.getDesc());
                    mapList.add(item);
                });
        return mapList;
    }

    public static <E extends BaseEnum> List<Map<String, Object>> getDictionaryList(Class<E> clazz,
                                                                                   String... props) {
        List<Map<String, Object>> mapList = new ArrayList<>();
        Arrays.stream(clazz.getEnumConstants())
                .forEach(enumItem -> {
                    Map<String, Object> item = new HashMap<>(props.length);
                    for (String prop : props) {
                        try {
                            String methodName = "get" + StringUtils.capitalize(prop);
                            Method method = ReflectionUtils.findMethod(clazz, methodName);
                            Assert.notNull(method, "method not found");
                            item.put(prop, method.invoke(enumItem));
                        } catch (IllegalAccessException | InvocationTargetException e) {
                            log.error(e.getMessage(), e);
                        }
                    }
                    mapList.add(item);
                });
        return mapList;
    }

    @SafeVarargs
    public static <E extends BaseEnum> List<Map<String, Object>> getDictionaryList(Class<E> clazz,
                                                                                   IFunction<E, ?>... function) {
        List<Map<String, Object>> mapList = new ArrayList<>();

        Arrays.stream(clazz.getEnumConstants())
                .forEach(enumItem -> {
                    Map<String, Object> item = new HashMap<>(function.length);
                    for (IFunction<E, ?> fn : function) {
                        item.put(Reflections.fnToFieldName(fn), fn.apply(enumItem));
                    }
                    mapList.add(item);
                });
        return mapList;
    }
}
